﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Nody;

namespace GameStateManagement
{
    enum SlideTransitionState
    {
        SlidingOn,
        SlidingOff,
        Off,
        On
    };

    public class InventoryMenuScreen : GameScreen
    {
        #region Fields


        Inventory inventory;
        ContentManager content;

        Vector2 RolledIn = new Vector2(24, 718);
        Vector2 RolledOut = new Vector2(24, 452);
        Vector2 ItemsSize = new Vector2(54, 50);
        Vector2 ItemsSpan = new Vector2(16, 15);
        Vector2 FirstItemPos = new Vector2(37, 70);
        int ItemsByLine = 13;
        Vector2 position;
        Texture2D background;

        public bool IsShowed { get { return (slideState == SlideTransitionState.On); } }

        SlideTransitionState slideState;

        public TimeSpan PositionTransitionOnTime
        {
            get { return PositiontransitionOnTime; }
            protected set { PositiontransitionOnTime = value; }
        }

        TimeSpan PositiontransitionOnTime = TimeSpan.Zero;

        public TimeSpan PositionTransitionOffTime
        {
            get { return PositiontransitionOffTime; }
            protected set { PositiontransitionOffTime = value; }
        }

        TimeSpan PositiontransitionOffTime = TimeSpan.Zero;

        public float PositionTransitionPosition
        {
            get { return positionTransitionPosition; }
            protected set { positionTransitionPosition = value; }
        }

        float positionTransitionPosition = 0;

        #endregion

        #region Initialization

        public InventoryMenuScreen()
        {
            PositionTransitionOffTime = TimeSpan.FromSeconds(0.2);
            PositionTransitionOnTime = TimeSpan.FromSeconds(0.2);
            slideState = SlideTransitionState.Off;
            this.IsPopup = true;
            this.HandlesInput = false;
            inventory = new Inventory();
        }

        public override void LoadContent()
        {
            if (content == null)
                content = new ContentManager(ScreenManager.Game.Services, "Content");

            background = content.Load<Texture2D>("ui/inventory/Inventory");
            inventory.LoadContent();

            ScreenManager.Game.ResetElapsedTime();
        }

        public override void UnloadContent()
        {
            content.Unload();
        }

        #endregion

        #region Update and Draw

        public override void Update(GameTime gameTime, bool otherScreenHasFocus,
                                                       bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, false);

            switch (slideState)
            {
                case SlideTransitionState.Off:
                    position = RolledIn;
                    break;
                case SlideTransitionState.On:
                    position = RolledOut;
                    break;
                case SlideTransitionState.SlidingOff:
                    if (!TransitionSlide(gameTime, PositionTransitionOffTime, -1))
                        slideState = SlideTransitionState.Off;
                    break;
                case SlideTransitionState.SlidingOn:
                    if (!TransitionSlide(gameTime, PositionTransitionOnTime, 1))
                        slideState = SlideTransitionState.On;
                    break;
            }

            if (IsActive)
            {
                // TODO: this game isn't very fun! You could probably improve
                // it by inserting something more interesting in this space :-)
            }
        }

        private bool TransitionSlide(GameTime gameTime, TimeSpan time, int direction)
        {
            // How much should we move by?
            float transitionDelta;

            if (time == TimeSpan.Zero)
                transitionDelta = 1;
            else
                transitionDelta = (float)(gameTime.ElapsedGameTime.TotalMilliseconds /
                                          time.TotalMilliseconds);

            // Update the transition position.
            positionTransitionPosition += transitionDelta * direction;

            Vector2 displacement = (RolledOut - RolledIn) * transitionDelta * direction;
            position = new Vector2(position.X + displacement.X, position.Y + displacement.Y);

            // Did we reach the end of the transition?
            if (((direction < 0) && (positionTransitionPosition <= 0)) ||
                ((direction > 0) && (positionTransitionPosition >= 1)))
            {
                positionTransitionPosition = MathHelper.Clamp(positionTransitionPosition, 0, 1);
                return false;
            }
            else // Otherwise we are still busy transitioning.
                return true;
        }

        public override void Draw(GameTime gameTime)
        {
            // Our player and enemy are both actually just text strings.
            SpriteBatch spriteBatch = ScreenManager.SpriteBatch;

            spriteBatch.Begin();

            spriteBatch.Draw(background, position, Color.White);

            int itemCount = 0;
            Vector2 itemPos = position + FirstItemPos;
            foreach (Item i in inventory.Items)
            {
                spriteBatch.Draw(i.InventoryIcon, itemPos, Color.White);
                itemCount++;
                if ((itemCount % ItemsByLine) == 0)
                    itemPos = position + new Vector2(FirstItemPos.X, FirstItemPos.Y + ((ItemsSize.Y + ItemsSpan.Y) * (itemCount / ItemsByLine)));
                else
                    itemPos = position + new Vector2(FirstItemPos.X + ((ItemsSize.X + ItemsSpan.X) * (itemCount % ItemsByLine)), FirstItemPos.Y + ((ItemsSize.Y + ItemsSpan.Y) * (int)(itemCount / ItemsByLine)));
            }

            spriteBatch.End();
        }

        #endregion

        #region Public Methods

        public void Show()
        {
            slideState = SlideTransitionState.SlidingOn;
        }

        public void Hide()
        {
            slideState = SlideTransitionState.SlidingOff;
        }

        public void AddItem(Item i)
        {
            inventory.AddItem(i);
        }
        
        public void RemoveItem(Item i)
        {
            inventory.RemoveItem(i);
        }

        #endregion
    }
}
